package testdomainpubliccontest;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.Collection;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import conditionsAPI.AndDomainCondition;
import conditionsAPI.ConditionDuplicatedException;
import conditionsAPI.ConditionsConfiguration;
import conditionsAPI.NotDomainCondition;

public class TestDomainPublicContest {

	private TractorCondition tractorConditionA;
	private TractorCondition tractorConditionB;
	private TractorCondition tractorConditionC;
	private EmployeesCondition employeesCondition;
	private CostCondition costCondition;
	private NotDomainCondition notCostCondition;
	private AndDomainCondition andCondition1;
	private AndDomainCondition andCondition2;
	
	@Before
	public void setUp(){
		try {
			this.tractorConditionA = new TractorCondition("A");
			this.tractorConditionB = new TractorCondition("B");
			this.tractorConditionC = new TractorCondition("C");
			this.andCondition1 = new AndDomainCondition("D");
			this.employeesCondition = new EmployeesCondition("E");
			this.costCondition = new CostCondition("F");
			this.notCostCondition = new NotDomainCondition(this.costCondition);
			this.andCondition2 = new AndDomainCondition("G");
			
		} catch (ConditionDuplicatedException e) {
			e.printStackTrace();
		}
		
		this.tractorConditionA.setType("A");
		this.tractorConditionA.setQuantity(2);
		this.tractorConditionB.setType("B");
		this.tractorConditionB.setQuantity(1);
		this.tractorConditionC.setType("C");
		this.tractorConditionC.setQuantity(1);
		this.andCondition1.addPreCondition(tractorConditionA);
		this.andCondition1.addPreCondition(tractorConditionB);
		this.andCondition1.addPreCondition(tractorConditionC);
		
		this.employeesCondition.setQuantity(100);
		this.costCondition.setValue(1000000);
		this.andCondition2.addPreCondition(this.andCondition1);
		this.andCondition2.addPreCondition(this.employeesCondition);
		this.andCondition2.addPreCondition(this.notCostCondition);
		
	}
	
	@After
	public void tearDown(){
		ConditionsConfiguration.reset();
	}
	
	@Test
	public void setTargetAndConditionAllConditionsFulfilledCheckTargetResultEqualsAndCondition(){
		ConditionsConfiguration.setTarget(this.andCondition2);
		Collection<Object> requirements = new ArrayList<Object>();
		requirements.add(new Requirement(Requirement.Description.TRACTOR, 2, "A"));
		requirements.add(new Requirement(Requirement.Description.TRACTOR, 1, "B"));
		requirements.add(new Requirement(Requirement.Description.TRACTOR, 1, "C"));
		requirements.add(new Requirement(Requirement.Description.EMPLOYEES, 100, ""));
		requirements.add(new Requirement(Requirement.Description.COST, 999999, ""));
		
		ConditionsConfiguration.processObjects(requirements);
		
		assertEquals(this.andCondition2.getId(),ConditionsConfiguration.getLastConditionFulfilled());
	}
	
	@Test
	public void setTargetAndConditionAllConditionsFulfilledCheckTargetAndConditionIsTrue(){
		ConditionsConfiguration.setTarget(this.andCondition2);
		Collection<Object> requirements = new ArrayList<Object>();
		requirements.add(new Requirement(Requirement.Description.TRACTOR, 2, "A"));
		requirements.add(new Requirement(Requirement.Description.TRACTOR, 1, "B"));
		requirements.add(new Requirement(Requirement.Description.TRACTOR, 1, "C"));
		requirements.add(new Requirement(Requirement.Description.EMPLOYEES, 100, ""));
		requirements.add(new Requirement(Requirement.Description.COST, 999999, ""));
		
		ConditionsConfiguration.processObjects(requirements);
		
		assertTrue(this.andCondition2.isTrue());
	}

	@Test
	public void setTargetAndConditionSomeConditionsFulfilledCheckTargetResultIsEmpty(){
		ConditionsConfiguration.setTarget(this.andCondition2);
		Collection<Object> requirements = new ArrayList<Object>();
		requirements.add(new Requirement(Requirement.Description.TRACTOR, 2, "A"));
		requirements.add(new Requirement(Requirement.Description.TRACTOR, 2, "B"));
		requirements.add(new Requirement(Requirement.Description.TRACTOR, 1, "C"));
		requirements.add(new Requirement(Requirement.Description.EMPLOYEES, 100, ""));
		requirements.add(new Requirement(Requirement.Description.COST, 1000000, ""));
		
		ConditionsConfiguration.processObjects(requirements);
		
		assertEquals("",ConditionsConfiguration.getLastConditionFulfilled());
	}
	
	@Test
	public void setTargetAndConditionSomeConditionsFulfilledCheckAndConditionIsFalse(){
		ConditionsConfiguration.setTarget(this.andCondition2);
		Collection<Object> requirements = new ArrayList<Object>();
		requirements.add(new Requirement(Requirement.Description.TRACTOR, 2, "A"));
		requirements.add(new Requirement(Requirement.Description.TRACTOR, 2, "B"));
		requirements.add(new Requirement(Requirement.Description.TRACTOR, 1, "C"));
		requirements.add(new Requirement(Requirement.Description.EMPLOYEES, 100, ""));
		requirements.add(new Requirement(Requirement.Description.COST, 1000000, ""));
		
		ConditionsConfiguration.processObjects(requirements);
		
		assertFalse(this.andCondition2.isTrue());
	}
}
